home *** CD-ROM | disk | FTP | other *** search
-
- #include "main.h"
-
- STENCIL StencilShadow;
-
- //------------------------------------------------------------------
- // Name: STENCIL()
- // Desc: konstruktor
- //------------------------------------------------------------------
- STENCIL::STENCIL()
- {
- SquareVB = NULL;
-
- NumVertices = 0;
-
- LightPosition = Get3D( 100.0f,100.0f,100.0f);
-
- }
-
- //------------------------------------------------------------------
- // Name: ~STENCIL()
- // Desc: destruktor
- //------------------------------------------------------------------
- STENCIL::~STENCIL()
- {
-
- if (SquareVB != NULL)
- SquareVB->Release();
-
- }
-
-
- //------------------------------------------------------------------
- // Name: Initialize()
- // Desc: inicializacia
- //------------------------------------------------------------------
- void STENCIL::Initialize()
- {
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
- LogPrint("Inicializuje Stencil");
-
- //////////////
- //Big Square//
- //////////////
- if (FAILED(g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEXSTENCILSQUARE ),
- D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEXSTENCILSQUARE ,
- D3DPOOL_DEFAULT, &SquareVB, NULL )))
- {
- LogPrint(" Chyba pri vytvarani VB");
- }
- else
- {
- LogPrint(" Vertex Buffer vytvoreny");
- }
-
-
- CUSTOMVERTEXSTENCILSQUARE *v;
-
- SquareVB->Lock( 0, 0, (void**)&v, 0 );
- {
- v[0].p = D3DXVECTOR4( 0, (float)Engine.Height, 0.0f, 1.0f );
- v[1].p = D3DXVECTOR4( 0, 0, 0.0f, 1.0f );
- v[2].p = D3DXVECTOR4( (float)Engine.Width, (float)Engine.Height, 0.0f, 1.0f );
- v[3].p = D3DXVECTOR4( (float)Engine.Width, 0.0f, 0.0f, 1.0f );
- v[0].color = 0x60000000;
- v[1].color = 0x60000000;
- v[2].color = 0x60000000;
- v[3].color = 0x60000000;
- }
- SquareVB->Unlock();
-
-
- }
-
-
- //------------------------------------------------------------------
- // Name: AddEdge()
- // Desc: prida quad od hrany
- //------------------------------------------------------------------
- void STENCIL::AddEdge(VECTOR3D V1,VECTOR3D V2)
- {
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
-
- Edge[NumEdges].V1 = V1;
- Edge[NumEdges].V2 = V2;
- NumEdges++;
-
- }
-
- //------------------------------------------------------------------
- // Name: ProcessEdge()
- // Desc: z hrany urobi quad
- //------------------------------------------------------------------
- void STENCIL::AddQuad(VECTOR3D V1,VECTOR3D V2,VECTOR3D LightPos)
- {
-
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
-
- VECTOR3D Sme1,Sme2;
- Sub(&Sme1,V1,LightPos);
- Sub(&Sme2,V2,LightPos);
-
- VECTOR3D E0 ;
- VECTOR3D E1 ;
- VECTOR3D E2 ;
- VECTOR3D E3 ;
-
- E0.X = V1.X ;
- E0.Y = V1.Y ;
- E0.Z = V1.Z ;
-
- E1.X = V2.X ;
- E1.Y = V2.Y ;
- E1.Z = V2.Z ;
-
- E2.X = V1.X + Sme1.X*100.0f;
- E2.Y = V1.Y + Sme1.Y*100.0f;
- E2.Z = V1.Z + Sme1.Z*100.0f;
-
- E3.X = V2.X + Sme2.X*100.0f;
- E3.Y = V2.Y + Sme2.Y*100.0f;
- E3.Z = V2.Z + Sme2.Z*100.0f;
-
- /////
- //1//
- /////
- Vertices[NumVertices].x = E0.X;
- Vertices[NumVertices].y = E0.Y;
- Vertices[NumVertices].z = E0.Z;
- NumVertices++;
-
- Vertices[NumVertices].x = E1.X;
- Vertices[NumVertices].y = E1.Y;
- Vertices[NumVertices].z = E1.Z;
- NumVertices++;
-
- Vertices[NumVertices].x = E2.X;
- Vertices[NumVertices].y = E2.Y;
- Vertices[NumVertices].z = E2.Z;
- NumVertices++;
-
- /////
- //2//
- /////
- Vertices[NumVertices].x = E2.X;
- Vertices[NumVertices].y = E2.Y;
- Vertices[NumVertices].z = E2.Z;
- NumVertices++;
-
- Vertices[NumVertices].x = E1.X;
- Vertices[NumVertices].y = E1.Y;
- Vertices[NumVertices].z = E1.Z;
- NumVertices++;
-
- Vertices[NumVertices].x = E3.X;
- Vertices[NumVertices].y = E3.Y;
- Vertices[NumVertices].z = E3.Z;
- NumVertices++;
-
- }
-
- //------------------------------------------------------------------
- // Name: ProcessEdge()
- // Desc: Vyberie iba hrany ktore s nikim nesusedia
- //------------------------------------------------------------------
- void STENCIL::ProcessEdge(VECTOR3D LightPos)
- {
-
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
-
- int NumIdent = 0,i,u;
-
- for (i=0;i<NumEdges;i++)
- {
- NumIdent = 0;
-
- for (u=0;u<NumEdges;u++)
- {
- if(( (Edge[u].V1.X == Edge[i].V1.X && Edge[u].V1.Y == Edge[i].V1.Y && Edge[u].V1.Z == Edge[i].V1.Z) &&
- (Edge[u].V2.X == Edge[i].V2.X && Edge[u].V2.Y == Edge[i].V2.Y && Edge[u].V2.Z == Edge[i].V2.Z) )||
- ( (Edge[u].V1.X == Edge[i].V2.X && Edge[u].V1.Y == Edge[i].V2.Y && Edge[u].V1.Z == Edge[i].V2.Z) &&
- (Edge[u].V2.X == Edge[i].V1.X && Edge[u].V2.Y == Edge[i].V1.Y && Edge[u].V2.Z == Edge[i].V1.Z) ))
- {
- NumIdent++;
- }
- }
-
- if (NumIdent == 1)
- {
- AddQuad(Edge[i].V1,Edge[i].V2,LightPos);
- }
-
-
- }
-
- }
-
- //------------------------------------------------------------------
- // Name: RenderShadowQuads()
- // Desc: vyrenderuje quady
- //------------------------------------------------------------------
- void STENCIL::RenderShadowQuads()
- {
-
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
- g_pd3dDevice->SetFVF( D3DFVF_XYZ );
- g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, NumVertices/3,
- Vertices, sizeof(D3DXVECTOR3) );
-
-
- }
-
- //------------------------------------------------------------------
- // Name: RenderShadow()
- // Desc: vyrenderuje hotovy tien
- //------------------------------------------------------------------
- void STENCIL::RenderShadow()
- {
-
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
- RenderShadowBuffer();
- RenderShadowScreen();
-
- //reset
- NumVertices = 0;
- NumEdges = 0;
-
- }
-
- //------------------------------------------------------------------
- // Name: RenderShadowBuffer()
- // Desc: vyrenderuje tien do stencil bufferu
- //------------------------------------------------------------------
- void STENCIL::RenderShadowBuffer()
- {
-
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
- // Disable z-buffer writes (note: z-testing still occurs), and enable the
- // stencil-buffer
- g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
-
- // Dont bother with interpolating color
- g_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
-
- // Set up stencil compare fuction, reference value, and masks.
- // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
- // Note: since we set up the stencil-test to always pass, the STENCILFAIL
- // renderstate is really not needed.
-
- g_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ); //ak je stencil test false
- g_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); //ak je stencil test a ztest true
-
- // If z-test passes, inc/decrement stencil buffer value
- g_pd3dDevice->SetRenderState( D3DRS_STENCILREF, 0x0 );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff );
-
- // Make sure that no pixels get drawn to the frame buffer
- g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
-
-
- Engine.SetZBuffer(true);
-
- ///////////////////
- //increment Front//
- ///////////////////
-
- //increment
- //ak nieje pixel vidiet - zfail (ztest = false), pricitaj jednotu
- g_pd3dDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR );
-
- //fron culling
- g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
-
- // Draw front-side of shadow volume in stencil/z only
- RenderShadowQuads();
-
-
- //////////////////
- //decrement Back//
- //////////////////
-
- // Decrement stencil buffer value
- // ak nieje pixel vidiet - zfail (ztest = false), odcitaj jednotu
- g_pd3dDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR );
-
- // Now reverse cull order so back sides of shadow volume are written.
- g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
-
- // Draw back-side of shadow volume in stencil/z only
- RenderShadowQuads();
-
-
- //reset
- Engine.ResetToDefault();
- Engine.SetBlendNone();
-
- }
-
- //------------------------------------------------------------------
- // Name: RenderShadowScreen()
- // Desc: vyrenderuje tien (stencil buffer) na obrazovku
- //------------------------------------------------------------------
- void STENCIL::RenderShadowScreen()
- {
- //ak nieje zapnuty stencil prec
- if (Engine.StencilShadows == false)
- return;
-
- // Set render states
- g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, TRUE );
- g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
- g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
- g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
-
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
- g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
-
- // Only write where stencil value >= 1 (count indicates # of shadows that
- // overlap that pixel)
- g_pd3dDevice->SetRenderState( D3DRS_STENCILREF, 0x1 );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL );
- g_pd3dDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_KEEP );
-
- // Draw a big, gray square
- g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEXSTENCILSQUARE );
- g_pd3dDevice->SetStreamSource( 0, SquareVB, 0, sizeof(CUSTOMVERTEXSTENCILSQUARE) );
- g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
-
- // Restore render states
- Engine.ResetToDefault();
- Engine.SetBlendNone();
-
- }
-
-
-
-